/*
 *  Copyright (c) 2013, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

package com.facebook.rebound;

import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.miscservices.timeutility.Time;

/**
 * Android version of the spring looper that uses the most appropriate frame callback mechanism
 * available.  It uses a
 * {@link EventHandler}.
 */
abstract class AndroidSpringLooperFactory {

    /**
     * Create an Android {@link com.facebook.rebound.SpringLooper} for the detected Android platform.
     *
     * @return a SpringLooper
     */
    public static SpringLooper createSpringLooper() {

        return LegacyAndroidSpringLooper.create();
    }

    /**
     * The base implementation of the Android spring looper, using a {@link EventHandler} for the
     * frame callbacks.
     */
    private static class LegacyAndroidSpringLooper extends SpringLooper {

        private final EventHandler mHandler;
        private final Runnable mLooperRunnable;
        private boolean mStarted;
        private long mLastTime;

        /**
         * @return an Android spring looper using a new {@link EventHandler} instance
         */
        public static SpringLooper create() {
            return new LegacyAndroidSpringLooper(new EventHandler(EventRunner.getMainEventRunner()));
        }

        public LegacyAndroidSpringLooper(EventHandler handler) {
            mHandler = handler;
            mLooperRunnable = new Runnable() {
                @Override
                public void run() {
                    if (!mStarted || mSpringSystem == null) {
                        return;
                    }
                    long currentTime = Time.getRealActiveTime();

                    mSpringSystem.loop(currentTime - mLastTime);
                    mHandler.postTask(mLooperRunnable, ChoreographerCompat.ONE_FRAME_MILLIS);
                }
            };
        }

        @Override
        public void start() {
            if (mStarted) {
                return;
            }
            mStarted = true;
            mLastTime = Time.getRealActiveTime();
            mHandler.removeTask(mLooperRunnable);
            mHandler.postTask(mLooperRunnable, ChoreographerCompat.ONE_FRAME_MILLIS);
        }

        @Override
        public void stop() {
            mStarted = false;
            mHandler.removeTask(mLooperRunnable);
        }
    }
}